#ifndef UTILS_REAL_MULTI_H
#define UTILS_REAL_MULTI_H

#include <iostream>
using std::ostream;

#include <string>
using std::string;

#include <gmpxx.h>

#define REAL_MULTI_PRECISION 128

class RealMulti {

public:
	friend ostream& operator<<(ostream&, const RealMulti&);
//	static const RealMulti NaN;
	static const RealMulti PI;

	/**
	 * Initialise to 0.
	 */
	RealMulti();
	RealMulti(const string& s);
	RealMulti(const RealMulti& r);
	RealMulti(const mpf_class& r);
	RealMulti(double d);
	RealMulti(long l);
	RealMulti(int i);

	operator double() const;

	const RealMulti& operator=(double d);
	const RealMulti& operator=(const RealMulti& r);

	RealMulti operator+() const;
	RealMulti operator-() const;

	RealMulti operator+(const RealMulti& r) const;
	RealMulti operator-(const RealMulti& r) const;
	RealMulti operator*(const RealMulti& r) const;
	RealMulti operator/(const RealMulti& r) const;

	const RealMulti& operator+=(const RealMulti& r);
	const RealMulti& operator-=(const RealMulti& r);
	const RealMulti& operator*=(const RealMulti& r);
	const RealMulti& operator/=(const RealMulti& r);

	bool operator>(const RealMulti& r) const;
	bool operator<(const RealMulti& r) const;
	bool operator==(const RealMulti& r) const;
	bool operator!=(const RealMulti& r) const;

	void setToNaN(bool flag);
	bool isNaN() const;
	RealMulti abs() const;

private:

	mpf_class _value;
	bool      _isNaN;
};

ostream& operator<<(ostream& os, const RealMulti& r);

#endif	// UTILS_REAL_MULTI_H

